package top.kangyaocoding.ecommerce.impl;

import io.github.resilience4j.ratelimiter.RateLimiter;
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.kangyaocoding.ecommerce.IRateLimiterService;

import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 描述: 限流服务实现
 *
 * @author K·Herbert
 * @since 2025-03-23 01:10
 */
@Slf4j
@Service
public class RateLimiterService implements IRateLimiterService {
    private final RateLimiterRegistry rateLimiterRegistry;
    private final ConcurrentHashMap<String, RateLimiter> userLimiters = new ConcurrentHashMap<>();

    public RateLimiterService() {
        this.rateLimiterRegistry = RateLimiterRegistry.ofDefaults();
    }

    // 全局限流器
    @Override
    public RateLimiter getGlobalRateLimiter() {
        return rateLimiterRegistry.rateLimiter("global", RateLimiterConfig.custom()
                .limitRefreshPeriod(Duration.ofSeconds(25))  // 10 秒刷新
                .limitForPeriod(500)  // 10 秒最多 500 请求
                .timeoutDuration(Duration.ofMillis(50))
                .build());
    }

    // 登录限流器（每个用户 1 分钟最多 5 次）
    @Override
    public RateLimiter getLoginRateLimiter(String userId) {
        return userLimiters.computeIfAbsent("login:" + userId, key -> RateLimiter.of(key, RateLimiterConfig.custom()
                .limitRefreshPeriod(Duration.ofMinutes(1)) // 每 1 分钟刷新
                .limitForPeriod(5) // 1 分钟最多 5 个请求
                .timeoutDuration(Duration.ofMillis(100))
                .build()));
    }

    // 验证码限流器（10 秒 1 次）
    @Override
    public RateLimiter getVerificationCodeLimiter(String userId) {
        return userLimiters.computeIfAbsent("verification:" + userId, key -> RateLimiter.of(key, RateLimiterConfig.custom()
                .limitRefreshPeriod(Duration.ofMinutes(1)) // 每 1 分钟刷新
                .limitForPeriod(1) // 1 分钟 1 次
                .timeoutDuration(Duration.ofMillis(100))
                .build()));
    }

    // 信息更新限流器
    @Override
    public RateLimiter getUpdateLimiter(String userId) {
        return userLimiters.computeIfAbsent("update:" + userId, key -> RateLimiter.of(key, RateLimiterConfig.custom()
                .limitRefreshPeriod(Duration.ofSeconds(60)) // 每 60 秒刷新
                .limitForPeriod(2) // 1 分钟 最多 1 次
                .timeoutDuration(Duration.ofMillis(100))
                .build()));
    }
}
